package wodegua.d29_多线程;

/**
 * 什么是线程安全问题?
 * ●多个线程，同时操作同一个共享资源的时候，可能会出现业务安全问题。
 *
 * 取钱的线程安全问题
 * ●场景:小明和小红是一对夫妻，他们有一个共同的账户，余额是10万元，如果小明和小红同时来取钱，并且2人各自都在取钱10万元，可能会出现什么问题呢?
 *
 * 分析:
 * 1:需要提供一个账户类，接着创建一个账户对象代表2个人的共享账户
 * 2:需要定义一个线程类(用于创建两个线程，分别代表小明和小红)。
 * 3:创建2个线程，传入同一个账户对象给2个线程处理。
 * 4:启动2个线程，同时去同一个账户对象中取钱10万。
 *
 *
 * 线程同步
 * ●解决线程安全问题的方案。
 *
 * 线程同步的思想
 * ●让多个线程实现先后依次访问共享资源，这样就解决了安全问题，
 *
 * 线程同步的常见方案
 * 加锁:每次只允许一个线程加锁，加锁后才能进入访问，访问完毕后自动解锁，然后其他线程才能再加锁进来
 *
 */
public class d2_thread_safe {
    public static void main(String[] args) {
        Account account = new Account("id-1101",100000);
        new DrawThread(account, "小明").start();
        new DrawThread(account, "小红").start();

    }
}

class Account{
    private String cardId;
    private double money;

    public Account() {
    }

    public Account(String cardId, double money) {
        this.cardId = cardId;
        this.money = money;
    }

    public void DrawMoney(double money){
        String name = Thread.currentThread().getName();
        if (this.money >= money) {
            System.out.println(name + "来取" + money);
            this.money -= money;
            System.out.println(name + "来取" + money + "后，余额="+this.money);
        } else {
            System.out.println(name + "来取钱余额不足");
        }
    }

    public String getCardId() {
        return cardId;
    }

    public void setCardId(String cardId) {
        this.cardId = cardId;
    }

    public double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }
}

class DrawThread extends Thread{
    private Account account;
    public DrawThread() {
    }

    public DrawThread(Account account, String name) {
        super(name);
        this.account = account;
    }

    @Override
    public void run() {
        account.DrawMoney(100000);
    }
}